

/*
 *  Copyright 2010 De Gregorio Daniele.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

/* 
 * Edited by Conductive ink group
 * 
 * */

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;

public class DraggableComponent extends JPanel {

    /** If sets <b>TRUE</b> this component is draggable */
    private boolean draggable = true;
    /** 2D Point representing the coordinate where mouse is, relative parent container */
    protected Point anchorPoint;
    /** Default mouse cursor for dragging action */
    protected Cursor draggingCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
    /** If sets <b>TRUE</b> when dragging component, it will be painted over each other (z-Buffer change) */
    protected boolean overbearing = false;
   
    public DraggableComponent() {
        addDragListeners();
        setOpaque(false);
        
        
       
    }

    /**
     * We have to define this method because a JComponent is a void box. So we have to
     * define how it will be painted. We create a simple filled rectangle.
     *
     * @param g Graphics object as canvas
     */
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        
    }

    /**
     * Add Mouse Motion Listener with drag function
     */
    private void addDragListeners() {
        /** This handle is a reference to THIS beacause in next Mouse Adapter "this" is not allowed */
        final DraggableComponent handle = this;
        addMouseMotionListener(new MouseAdapter() {
        	
        	//mode = 0 is dragging; 1 is resizing
        	int mode = 0;
        	int preX = 0;
        	int preY = 0;
        	
            @Override
            public void mouseMoved(MouseEvent e) {
               
            	anchorPoint = e.getPoint();
				if(anchorPoint.x <= getWidth() && anchorPoint.x >= getWidth() - 10 && anchorPoint.y >= getHeight() - 10 && anchorPoint.y <= getHeight()){
					setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
					preX = e.getPoint().x;
	            	preY = e.getPoint().y;
					mode = 1;
	              }
	              else
	              {
	                setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
	                mode = 0;
	              }
            }
            
            @Override
            public void mouseDragged(MouseEvent e) {
            	
            	if(mode==0){
	                int anchorX = anchorPoint.x;
	                int anchorY = anchorPoint.y;
	
	                Point parentOnScreen = getParent().getLocationOnScreen();
	                Point mouseOnScreen = e.getLocationOnScreen();
	                Point position = new Point(mouseOnScreen.x - parentOnScreen.x - anchorX, mouseOnScreen.y - parentOnScreen.y - anchorY);
	                
	                //Image Boundaries 
	                if(position.x >= 500){
	                	position.x = 500; 
	                } 
	                if(position.x <= 0){
	                	position.x = 0; 
	                }
	                if(position.y <= 0){
	                	position.y = 0; 
	                }
	                if(position.y >= 290){
	                	position.y = 290;
	                }
	                
	                setLocation(position);
            	}
            	else if (mode==1)
            	{
            		int anchorX = e.getPoint().x;
                    int anchorY = e.getPoint().y;
                    
                    ((DraggableImageComponent)handle).grow(anchorX - preX, anchorY - preY);
                    
                    preX = anchorX;
                    preY = anchorY;
            	}

                //Change Z-Buffer if it is "overbearing"
                if (overbearing) {
                    getParent().setComponentZOrder(handle, 0);
                    repaint();
                }
            }
        });
        
        addMouseListener( new MouseListener(){

			@Override
			public void mouseClicked(MouseEvent arg0) {
				((DraggableImageComponent)handle).setSelection();
				
			}

			@Override
			public void mouseEntered(MouseEvent arg0) {
				
				if(((DraggableImageComponent)handle).isSelected()){
					//do nothing
				}
				else
				{
					setBorder(new LineBorder(Color.blue, 1));
				}
			}

			@Override
			public void mouseExited(MouseEvent arg0) {
				
				if(((DraggableImageComponent)handle).isSelected()){
					//do nothing
				}
				else
				{
					setBorder(null);
				}
				
			}

			@Override
			public void mousePressed(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void mouseReleased(MouseEvent arg0) {
				// TODO Auto-generated method stub
				
			}
        	
        });
    }


    /**
     * Remove all Mouse Motion Listener. Freeze component.
     */
    private void removeDragListeners() {
        for (MouseMotionListener listener : this.getMouseMotionListeners()) {
            removeMouseMotionListener(listener);
        }
        setCursor(Cursor.getDefaultCursor());
    }

    /**
     * Get the value of draggable
     *
     * @return the value of draggable
     */
    public boolean isDraggable() {
        return draggable;
    }

    /**
     * Set the value of draggable
     *
     * @param draggable new value of draggable
     */
    public void setDraggable(boolean draggable) {
        this.draggable = draggable;
        if (draggable) {
            addDragListeners();
        } else {
            removeDragListeners();
        }

    }

    /**
     * Get the value of draggingCursor
     *
     * @return the value of draggingCursor
     */
    public Cursor getDraggingCursor() {
        return draggingCursor;
    }

    /**
     * Set the value of draggingCursor
     *
     * @param draggingCursor new value of draggingCursor
     */
    public void setDraggingCursor(Cursor draggingCursor) {
        this.draggingCursor = draggingCursor;
    }

    /**
     * Get the value of overbearing
     *
     * @return the value of overbearing
     */
    public boolean isOverbearing() {
        return overbearing;
    }

    /**
     * Set the value of overbearing
     *
     * @param overbearing new value of overbearing
     */
    public void setOverbearing(boolean overbearing) {
        this.overbearing = overbearing;
    }
}
